package org.phona.object;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.phona.OnUserEventListener;
import org.phona.R;
import org.phona.index.IndexNode;

import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class ContactsAdapter extends BaseAdapter {

	LayoutInflater li;
	Context context;
	List<Contact> contactList=new ArrayList<Contact>();
	Map<String,Contact> contactMap=new HashMap<String,Contact>();
	Set<Contact> filtredContactSet = new HashSet<Contact>();
	List<Contact> filtredContactList = new ArrayList<Contact>();

	IndexNode rootIndexNode;
	String filter=null;

	Map<Character,Character> charToNumber=new HashMap<Character,Character>();
	OnUserEventListener onUserEventListener;
	
	public static final String TAG = "ContactsAdapter";
	

	public ContactsAdapter(Context context){
		this.context = context;
		li = LayoutInflater.from(context);		

		charToNumber.put(' ','1');
		charToNumber.put('a','2');
		charToNumber.put('b','2');
		charToNumber.put('c','2');

		charToNumber.put('d','3');
		charToNumber.put('e','3');
		charToNumber.put('d','3');

		charToNumber.put('g','4');
		charToNumber.put('h','4');
		charToNumber.put('i','4');

		charToNumber.put('j','5');
		charToNumber.put('k','5');
		charToNumber.put('l','5');

		charToNumber.put('m','6');
		charToNumber.put('n','6');
		charToNumber.put('o','6');

		charToNumber.put('p','7');
		charToNumber.put('q','7');
		charToNumber.put('r','7');
		charToNumber.put('s','7');

		charToNumber.put('t','8');
		charToNumber.put('u','8');
		charToNumber.put('v','8');

		charToNumber.put('w','9');
		charToNumber.put('x','9');
		charToNumber.put('y','9');
		charToNumber.put('z','9');

		rootIndexNode = new IndexNode();

	}

	public void init(){
		contactList.clear();
		contactMap.clear();
		filtredContactList.clear();
		filtredContactSet.clear();
		Long start = System.currentTimeMillis();
		Cursor c = getContactsFromContentProvider();
		Log.i(TAG,"Loading contacts in :"+(System.currentTimeMillis()-start));
		start = System.currentTimeMillis();
		if (c.moveToFirst()) {

			String name; 
			String phoneNumber; 
			int nameColumn = c.getColumnIndex(Data.DISPLAY_NAME); 
			int phoneColumn = c.getColumnIndex(Phone.NUMBER);

			do {
				// Get the field values
				name = c.getString(nameColumn);
				phoneNumber = c.getString(phoneColumn);
				//Log.i(TAG,"found phone "+phoneNumber);
				Contact current = contactMap.get(name.toLowerCase().intern());
				if(current==null){
					current = new Contact(name);
					contactList.add(current);
					contactMap.put(name.toLowerCase().intern(),current);
				}
				rootIndexNode.insert(encode(name), current);
				rootIndexNode.insert(phoneNumber, current);
				current.add(phoneNumber);

			} while (c.moveToNext());

		}
		Log.i(TAG,"Inserting contacts in SearchTree in :"+(System.currentTimeMillis()-start));
		//Log.d(TAG,rootIndexNode.display("  "));
		
	}

	Cursor getContactsFromContentProvider(){

		Cursor c = context.getContentResolver().query(Data.CONTENT_URI,
				new String[] {Data._ID,Data.DISPLAY_NAME, Phone.NUMBER,Phone.TYPE, Phone.LABEL},
				Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "' AND "+
				ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'"
				
				/*Phone.TYPE+"='"+Phone.TYPE_HOME+"' AND "+
				Data.DISPLAY_NAME+" like '%si%'"*/,
				null, null);
		return c;
	}



	@Override
	public int getCount() {
		
		return filter==null?contactList.size():filtredContactList.size();
	}

	@Override
	public Object getItem(int position) {
		Log.i(TAG,"gettingItem pos="+position);	
		return filter==null?contactList.get(position):filtredContactList.get(position);
	}

	@Override
	public long getItemId(int position) {
		Log.i(TAG,"gettingItemId pos="+position);
		return position;
	}

	class MyTag{
		public TextView text1;
		public TextView text1High;
		public TextView text1End;
		public TextView text2;
		public ImageView call;
	}
	
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		//Log.i(TAG,"gettingView pos="+position);
		MyTag holder;
		if(convertView==null){
			convertView = li.inflate(R.layout.contact_row, null);
			holder = new MyTag();
			holder.text1 = (TextView)convertView.findViewById(R.id.text1);
			holder.text1High = (TextView)convertView.findViewById(R.id.text1_highlight);
			holder.text1End = (TextView)convertView.findViewById(R.id.text1_end);
			holder.text2 = (TextView)convertView.findViewById(R.id.text2);
			holder.call = (ImageView)convertView.findViewById(R.id.call);
			convertView.setTag(holder);
		}else{
			holder = (MyTag)convertView.getTag();
		}
		
		fillText(holder.text1,holder.text1High,holder.text1End,holder.text2,holder.call,convertView, position, (filter==null?contactList:filtredContactList));
		/*
		TextView tv = (TextView)convertView.findViewById(R.id.text1);
		TextView tv2 = (TextView)convertView.findViewById(R.id.text2);
		ImageView call = (ImageView)convertView.findViewById(R.id.call);
		Log.i(TAG,"preview tv="+tv.getText());
		Log.i(TAG,"preview tv2="+tv2.getText());
		final int pos = position;
		final OnUserEventListener ouel = this.onUserEventListener;

		if(filter==null){

			tv.setText(contactList.get(position).getName());
			tv2.setText(contactList.get(position).getPhoneNumbers());
			call.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					ouel.onEvent(contactList.get(pos));
				}
			});
		}else{
			tv.setText(filtredContactList.get(position).getName());
			tv2.setText(filtredContactList.get(position).getPhoneNumbers());
			call.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					ouel.onEvent(filtredContactList.get(pos));
				}
			});
		}*/
		return convertView;
	}

	void fillText(TextView text1,TextView text1High,TextView text1End,TextView text2,ImageView call,View view,int position, List<Contact> list){
		final List<Contact> finalList = list;
		/*if(filter==null){
			
			text1.setText(list.get(position).getName());
		}else{
			String name = list.get(position).getName().toString();
			Integer beginIndex = name.indexOf(filter);
			text1.setText(name.substring(0,beginIndex));
			text1High.setText(name.substring(beginIndex,beginIndex+filter.length()));
			text1End.setText(name.substring(beginIndex+filter.length(),name.length()));
		}*/
		
		text1.setText(list.get(position).getName());
		text2.setText(list.get(position).getPhoneNumbers());
		final int pos = position;
		final OnUserEventListener ouel = this.onUserEventListener;

		call.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				ouel.onEvent(finalList.get(pos));
			}
		});
	}



	public void filter(String filter){
		filtredContactSet.clear();
		filtredContactList.clear();		
		if(filter.length()==0){
			this.filter=null;
		}else{
			this.filter=filter;
			rootIndexNode.search(filter, filtredContactSet);
			filtredContactList.addAll(filtredContactSet);			
			Log.i(TAG, "resultFound "+filtredContactSet);
		}
	}



	String encode(String name){
		String result = "";
		//String accentRemovedName = StringOperation.sansAccent(name);
		String accentRemovedName = name;
		for(Character c : accentRemovedName.toCharArray()){
			result+=getHash(c);
		}
		return result;

	}

	Character getHash(Character c){
		Character m = Character.toLowerCase(c);
		return charToNumber.get(m);


	}

	public void addOnUserEventListener(OnUserEventListener onUserEventListener) {
		this.onUserEventListener = onUserEventListener;
	}

}
